#include "ds18b20.h"
 
void delay_us(uint32_t nus)
{
  volatile unsigned int num;
  volatile unsigned int t;
 
  
  for (num = 0; num < nus; num++)
  {
    t = 11;
    while (t != 0)
    {
      t--;
    }
  }
}
 
/*18B20复位*/
void DS18B20_Reset(void)
{
	SET_DQ;    
  delay_us(2);
  CLR_DQ;                   //送出低电平复位信号
  delay_us(500);    
  SET_DQ;                   //释放数据线
  delay_us(45);	            //等待60us
	GET_DQ;            //检测存在脉冲    
  delay_us(182);             //等待设备释放数据线
}
 
/**************************************
从DS18B20读1字节数据
**************************************/
uint8_t DS18B20_ReadByte(void)
{
  uint8_t i;
  uint8_t dat = 0;
 
  for (i=0; i<8; i++)         //8位计数器
  {
    dat >>= 1;
    CLR_DQ;                   //开始时间片
    delay_us(2);               //延时等待
    SET_DQ;                   //准备接收
    delay_us(6);               //接收延时
    if(GET_DQ) 
      dat |= 0x80;            //读取数据
    delay_us(45);              //等待时间片结束
  }
  return dat;
}
 
/**************************************
向DS18B20写1字节数据
**************************************/
void DS18B20_WriteByte(uint8_t dat)
{
  uint8_t i;
  for (i=0;i<8;i++)             //8位计数器
  {
    CLR_DQ;                     //开始时间片
    delay_us(2);                //延时等待
    if(dat&0x01)		 //送出数据
			SET_DQ;
		else
			CLR_DQ;
		dat >>= 1;                 
    delay_us(45);               //等待时间片结束
    SET_DQ;                     //恢复数据线
    delay_us(1);                //恢复延时
  }
}
 
/*18B20main*/
float Get_18B20(void)
{
	uint8_t TPH;               //存放温度值的高字节
	uint8_t TPL;							 //存放温度值的低字节
	uint16_t i;
	float Temp18B20 = 0;
	
 	DS18B20_Reset();                //设备复位
  DS18B20_WriteByte(0xCC);        //跳过ROM命令
  DS18B20_WriteByte(0x44);        //开始转换命令
  delay_us(45);                    //等待转换完成
 
  DS18B20_Reset();                //设备复位
  DS18B20_WriteByte(0xCC);        //跳过ROM命令
  DS18B20_WriteByte(0xBE);        //读暂存存储器命令
  TPL = DS18B20_ReadByte();       //读温度低字节
  TPH = DS18B20_ReadByte();       //读温度高字节	    
	i = TPH;
	i <<= 8;
	i = i|TPL;
	
  Temp18B20 = i * 0.0625;
	
	return Temp18B20;
}



/******************************第二个************************************/
/*18B20复位*/
void DS18B20_Reset2(void)
{
	SET_DQ2;    
  delay_us(2);
  CLR_DQ2;                   //送出低电平复位信号
  delay_us(500);    
  SET_DQ2;                   //释放数据线
  delay_us(45);	            //等待60us
	GET_DQ2;            //检测存在脉冲    
  delay_us(182);             //等待设备释放数据线
}
 
/**************************************
从DS18B20读1字节数据
**************************************/
uint8_t DS18B20_ReadByte2(void)
{
  uint8_t i;
  uint8_t dat = 0;
 
  for (i=0; i<8; i++)         //8位计数器
  {
    dat >>= 1;
    CLR_DQ2;                   //开始时间片
    delay_us(2);               //延时等待
    SET_DQ2;                   //准备接收
    delay_us(6);               //接收延时
    if(GET_DQ2) 
      dat |= 0x80;            //读取数据
    delay_us(45);              //等待时间片结束
  }
  return dat;
}
 
/**************************************
向DS18B20写1字节数据
**************************************/
void DS18B20_WriteByte2(uint8_t dat)
{
  uint8_t i;
  for (i=0;i<8;i++)             //8位计数器
  {
    CLR_DQ2;                     //开始时间片
    delay_us(2);                //延时等待
    if(dat&0x01)		 //送出数据
			SET_DQ2;
		else
			CLR_DQ2;
		dat >>= 1;                 
    delay_us(45);               //等待时间片结束
    SET_DQ2;                     //恢复数据线
    delay_us(1);                //恢复延时
  }
}
 
/*18B20main*/
float Get2_18B20(void)
{
	uint8_t TPH;               //存放温度值的高字节
	uint8_t TPL;							 //存放温度值的低字节
	uint16_t i;
	float Temp18B20 = 0;
	
 	DS18B20_Reset2();                //设备复位
  DS18B20_WriteByte2(0xCC);        //跳过ROM命令
  DS18B20_WriteByte2(0x44);        //开始转换命令
  delay_us(45);                    //等待转换完成
 
  DS18B20_Reset2();                //设备复位
  DS18B20_WriteByte2(0xCC);        //跳过ROM命令
  DS18B20_WriteByte2(0xBE);        //读暂存存储器命令
  TPL = DS18B20_ReadByte2();       //读温度低字节
  TPH = DS18B20_ReadByte2();       //读温度高字节	    
	i = TPH;
	i <<= 8;
	i = i|TPL;
	
  Temp18B20 = i * 0.0625;
	
	return Temp18B20;
}

